package com.jushu.storbox.manager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.Context;

import com.jushu.storbox.ShareDriveApplication;
import com.jushu.storbox.database.DAOFactory;
import com.jushu.storbox.database.IFileDao;
import com.jushu.storbox.database.IFolderDao;
import com.jushu.storbox.database.IShareINodeDao;
import com.jushu.storbox.entities.DownloadObject;
import com.jushu.storbox.entities.FileInfo;
import com.jushu.storbox.entities.FolderInfo;
import com.jushu.storbox.entities.ShareINode;
import com.jushu.storbox.entities.UploadObject;
import com.jushu.storbox.util.LogUtil;
import com.huawei.sharedrive.sdk.android.modelV2.response.FileInfoResponseV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FolderResponse;
import com.huawei.sharedrive.sdk.android.modelV2.response.INodeShareV2;

public class CatchManager {

	private static CatchManager catchManager = null;
	private Context context;
	private IFileDao fileDao = null;
	private IFolderDao folderDao = null;
	
	private HashMap<String, DownloadObject> downloadMap 
		= new HashMap<String, DownloadObject>();

	private HashMap<String, UploadObject> uploadMap 
		= new HashMap<String, UploadObject>();
	
	private HashMap<INodeShareV2, ShareINode> shareINodeMap 
		= new HashMap<INodeShareV2, ShareINode>();

	private List<ShareINode> newShareShip = new ArrayList<ShareINode>();
	
	public static CatchManager getInstance() {
		if(catchManager == null) {
			catchManager = new CatchManager();
		}
		return catchManager;
	}
	
	private CatchManager() {
		this.context = null;
		this.fileDao = null;
		this.folderDao = null;
	}
	
	public void initCatch(Context context) {
		this.context = context;
		this.fileDao = null;
		this.folderDao = null;
	}
	
	public String getCurrentUserId() {
		return ShareDriveApplication.getInstance().getWnerID();
	}
	
	private IFileDao getFileDao() {
		if(fileDao == null) {
			if(context == null) {
				context = ShareDriveApplication.getInstance();
			}
			fileDao = DAOFactory.instance(context).getFileDao();
		}
		return fileDao;
	}
	
	private IFolderDao getFolderDao() {
		if(folderDao == null) {
			if(context == null) {
				context = ShareDriveApplication.getInstance();
			}
			folderDao = DAOFactory.instance(context).getFolderDao();
		}
		return folderDao;
	}
	
	public FileInfo getFileInfo(String ownerId, String fileId) {
		FileInfo catchFile = getFileDao().getFile(ownerId, fileId);
		if(catchFile == null) {
			catchFile = new FileInfo();
			catchFile.setId(fileId);
			catchFile.setOwnerBy(ownerId);
			catchFile.setCurrentUserId(getCurrentUserId());
		}
		return catchFile;
	}

	public FileInfo getFileInfo(FileInfoResponseV2 frServer) {
		return getFileInfo(frServer.getOwnedBy(), frServer.getId());
	}
	
	public void insertFileInfo(FileInfo fileInfo) {
	}
	
	public FolderInfo getFolderInfo(String ownerId, String folderId) {
		FolderInfo catchFolder = getFolderDao().getFolderById(ownerId, folderId);
		if(catchFolder == null) {
			catchFolder = new FolderInfo();
			catchFolder.setId(folderId);
			catchFolder.setOwnerBy(ownerId);
			catchFolder.setCurrentUserId(getCurrentUserId());
		}
		return catchFolder;
	}

	public FolderInfo getFolderInfo(FolderResponse item) {
		return getFolderInfo(item.getOwnedBy(), item.getId());
	}

	public void insertFolderInfo(FolderInfo node) {
	}
	
	private String genUploadKey(String ownerId, String folderId, String filePath) {
		return ownerId+"_"+folderId+"_"+filePath;
	}
	
	private String genUploadKey(UploadObject obj) {
		return genUploadKey(obj.getOwnerId(), obj.getParent(), obj.getLoctPath());
	}
	
	public UploadObject getUploadObject(String ownerId, String folderId, String filePath) {
		String uploadKey = genUploadKey(ownerId, folderId, filePath);
		UploadObject uploadObject = uploadMap.get(uploadKey);
		if(uploadObject == null) {
			uploadObject = DAOFactory.instance(context).getUploadFileDao()
					.getUploadFile(ownerId, folderId, filePath);
			if(uploadObject != null) {
				putUploadObject(uploadObject);
			}
		}
		return uploadObject;
	}
	
	public UploadObject getUploadObject(UploadObject obj) {
		return getUploadObject(obj.getOwnerBy(), obj.getParent(), obj.getLoctPath());
	}
	
	public void putUploadObject(UploadObject obj) {
		if(obj != null) {
			String uploadKey = genUploadKey(obj);
			uploadMap.put(uploadKey, obj);
		} else {
			LogUtil.e("CatchManager", "upload object is null!");
		}
	}
	
	public UploadObject removeUploadObject(UploadObject obj) {
		UploadObject tempObj = null;
		if(obj != null) {
			String uploadKey = genUploadKey(obj);
			tempObj = uploadMap.remove(uploadKey);
		} else {
			LogUtil.e("CatchManager", "upload object is null!");
		}
		return tempObj;
	}
	
	private String genDownloadKey(String ownerId, String resId) {
		return ownerId+"_"+resId;
	}
	private String genDownloadKey(DownloadObject object) {
		return genDownloadKey(object.getOwnerBy(), object.getId());
	}
	
	public DownloadObject getDownloadObject(String ownerId, String resId) {
		String keyWord = genDownloadKey(ownerId, resId);
		DownloadObject downloadObj =  downloadMap.get(keyWord );
		if(downloadObj == null) {
			downloadObj = DAOFactory.instance(context).getDownloadFileDao()
				.getDownloadFileById(resId, ownerId);
			if(downloadObj != null) {
				putDownloadObject(downloadObj);
			}
		}
		return downloadObj;
	}
	
	public DownloadObject getDownloadObject(DownloadObject downloadObj) {
		String keyWord = genDownloadKey(downloadObj);
		DownloadObject tempDownloadObj =  downloadMap.get(keyWord );
		if(tempDownloadObj == null) {
			tempDownloadObj = DAOFactory.instance(context).getDownloadFileDao()
				.getDownloadFileById(downloadObj.getId(), downloadObj.getOwnerBy());
			if(tempDownloadObj != null) {
				putDownloadObject(tempDownloadObj);
			}
		}
		return tempDownloadObj;
	}
	
	public void putDownloadObject(DownloadObject downloadObject) {
		if(downloadObject != null) {
			String keyObj = genDownloadKey(downloadObject);
			downloadMap.put(keyObj , downloadObject);
		} else {
			LogUtil.e("CatchManager", "download object is null!");
		}
	}
	
	public DownloadObject removeDownloadObject(DownloadObject downloadObject) {
		DownloadObject tempObj = null;
		if(downloadObject != null) {
			String keyObj = genDownloadKey(downloadObject);
			tempObj = downloadMap.remove(keyObj);
		} else {
			LogUtil.e("CatchManager", "download object is null!");
		}
		return tempObj;
	}
	
	public ShareINode getShareINode(INodeShareV2 keyObj) {
		ShareINode inode = shareINodeMap.get(keyObj);
		if(inode == null) {
			inode = DAOFactory.instance(context).getShareINodeDao()
					.getShareINode(keyObj);
			if(inode != null) {
				putShareINode(keyObj, inode);
			}
		}
		return inode;
	}
	
	public void putShareINode(INodeShareV2 keyObj, 
			ShareINode valueObject) {
		ShareINode tempValue = shareINodeMap.put(keyObj, valueObject);
		
		if(valueObject != null) {
			if(tempValue == null) {//maybe valueObject is new item
				synchronized(newShareShip) {
					if( valueObject != null 
						&& valueObject.getItemViewed() == IShareINodeDao.ITEM_NOT_VIEWED ) {
						if(!newShareShip.contains(valueObject)) {
							newShareShip.add(valueObject);
						}
					}
				}
			} else {//valueObject is old item
				synchronized(newShareShip) {
					if( valueObject != null 
						&& valueObject.getItemViewed() == IShareINodeDao.ITEM_NOT_VIEWED ) {
						if(newShareShip.contains(valueObject)) {
							newShareShip.remove(tempValue);
						}
						newShareShip.add(valueObject);
					}
				}
			}
		}
	}
	
	public void removeShareINode(INodeShareV2 keyObj) {
		ShareINode tempValue = shareINodeMap.get(keyObj);
		if(tempValue != null) {
			removeNewShareShipNode(keyObj);
			shareINodeMap.remove(keyObj);
		}
	}
	
	public int getNewShareShipCount() {
		synchronized(newShareShip) {
			return newShareShip.size();
		}
	}
	
	public void removeNewShareShipNode(INodeShareV2 keyObj) {
		 final ShareINode value = shareINodeMap.get(keyObj);
		synchronized(newShareShip) {
			newShareShip.remove(value);
		}
	}
}
